package com.tanhua.server.interceptor;

import com.tanhua.common.pojo.User;
import com.tanhua.common.utils.NoAuthorization;
import com.tanhua.common.utils.UserThreadLocal;
import com.tanhua.server.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @Author 王加鑫
 * @Date 2021/09/04 21:52
 * @Since JDK 1.8
 * 使用拦截器统一校验Token
 */
@Component
public class TokenInterceptor implements HandlerInterceptor {

    @Autowired
    private UserService userService;

    /**
     * 当结果为true的时候就放行，不进行拦截
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        /**
         * 如果不是方法处理器，不进行拦截，放行
         */
        if(!(handler instanceof HandlerMethod)){
            return true;
        }

        /**
         * 如果方法上标注了@NoAuthorization注解，不进行拦截，放行
         */
        if(((HandlerMethod) handler).hasMethodAnnotation(NoAuthorization.class)){
            return true;
        }

        //拦截进行逻辑处理
        //校验token
        String token = request.getHeader("Authorization");
        if(StringUtils.isNotEmpty(token)){
            //token有效
            User user = userService.queryUserByToken(token);
            if(null != user){
                //user有效，放入到UserThreadLocal中
                UserThreadLocal.set(user);
                return true;
            }
        }
        //到这说明token或者user无效,给用户响应一个无权限的状态码,进行拦截
        response.setStatus(401);
        return false;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //校验token对UserThreadLocal中数据进行删除
        UserThreadLocal.remove();
    }
}
